/**
 *  Copyright 2012 oliver.keusemann@googlemail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package de.xelerity.geolessi.srv.impl.poi.bahn;

import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import de.xelerity.geolessi.preferences.Preferences;
import de.xelerity.geolessi.srv.CacheService;
import de.xelerity.geolessi.srv.poi.HalteStellenGetterExecutorI;
import de.xelerity.geolessi.srv.poi.HalteStellenGetterFacadeI;
import de.xelerity.geolessi.test.Test;
import de.xelerity.geolessi.types.mixed.Koordinate;
import de.xelerity.geolessi.types.mixed.Sector;
import de.xelerity.geolessi.types.mixed.SectorClusterDef;
import de.xelerity.geolessi.types.poi.HalteStelle;
import de.xelerity.geolessi.types.poi.HalteStellenListe;
import de.xelerity.geolessi.types.poi.HaltestellenIDProvider;
import de.xelerity.geolessi.types.poi.NextAbfahrtInfo;
import de.xelerity.geolessi.types.verbindung.Linien;

public class HalteSellenGetterFacadeImpl implements HalteStellenGetterFacadeI {

	private static Log log = LogFactory.getLog(de.xelerity.geolessi.srv.impl.poi.bahn.HalteSellenGetterFacadeImpl.class);

	private static CacheService<HalteStellenListe> cacheServiceHSList = null;

	private static HalteStellenGetterExecutorI HSGetter;

	public HalteStellenListe getHalteStellen(Sector S, long pHalteStellenTypen) throws Exception {

		if (S == null)
			throw new IllegalArgumentException("Sektor == null");

		int cacheKey = S.hashCode();
		if (cacheServiceHSList == null) {
			cacheServiceHSList = new CacheService<HalteStellenListe>("HalteStellenListe.class");
		}

		HalteStellenListe HSList = cacheServiceHSList.get(cacheKey);
		if (HSList == null) {
			long radius = (long) (Math.sqrt(S.getMaxKatenLaenge() * S.getMaxKatenLaenge() * 2) / 2);
			HSList = getHalteStellen(S.getCenter(), radius, pHalteStellenTypen);
			cacheServiceHSList.put(cacheKey, HSList);
		}
		return HSList;
	}

	public HalteStellenListe getHalteStellen(Koordinate pMapCenter, double pSpanX, double pSpanY, long pHalteStellenTypen)
			throws Exception {

		Sector S1 = new Sector(1, 1);

		double radius1;

		if (pSpanX >= pSpanY) {
			radius1 = pMapCenter.distance(pMapCenter.getLatitude(), pMapCenter.getLongitude() + pSpanX) / 2.0;
		} else {
			radius1 = pMapCenter.distance(pMapCenter.getLatitude() + pSpanY, pMapCenter.getLongitude()) / 2.0;
		}

		if (1 == 1)
			return getHalteStellen(pMapCenter, (long) radius1, pHalteStellenTypen);

		SectorClusterDef sectorsInMapRegionArea = Sector.getSectorsInMapRegionArea(pMapCenter, pSpanX, pSpanY);

		if (sectorsInMapRegionArea == null)
			throw new Exception("sectorsInMapRegionArea == null");

		long AnzahlS = sectorsInMapRegionArea.getSectorAnzahl();

		if (AnzahlS < 17) {
			int cacheKey;
			HalteStellenListe HSList = null;
			if (cacheServiceHSList == null) {
				cacheServiceHSList = new CacheService<HalteStellenListe>("HalteStellenListe.class");
			}
			for (int x = sectorsInMapRegionArea.getSpanXStart(); x <= sectorsInMapRegionArea.getSpanXEnd(); x++)
				for (int y = sectorsInMapRegionArea.getSpanYStart(); y <= sectorsInMapRegionArea.getSpanYEnd(); y++) {
					Sector S = new Sector(x, y);
					cacheKey = S.hashCode();
					HSList = cacheServiceHSList.get(cacheKey);

				}
		}

		int cacheKey = S1.hashCode();
		if (cacheServiceHSList == null) {
			cacheServiceHSList = new CacheService<HalteStellenListe>("HalteStellenListe.class");
		}

		HalteStellenListe HSList = cacheServiceHSList.get(cacheKey);
		if (HSList == null) {
			long radius = (long) (Math.sqrt(S1.getMaxKatenLaenge() * S1.getMaxKatenLaenge() * 2) / 2);
			HSList = getHalteStellen(S1.getCenter(), radius, pHalteStellenTypen);
			cacheServiceHSList.put(cacheKey, HSList);
		}
		return HSList;
	}

	public HalteStellenListe getHalteStellen(Koordinate pCenterSearch, long pSearchRadiusM, long pHalteStellenTypen)
			throws Exception {
		if (HSGetter == null) {
			HSGetter = new HalteSellenGetterExecutorImpl();
		}
		return HSGetter.getHalteStellen(pCenterSearch, pSearchRadiusM, pHalteStellenTypen);
	}

	public static void main(String[] args) {

		Test.startTest();

		int cacheKey = 322;
		CacheService<Integer> cacheService1 = new CacheService<Integer>("sLinien.class");

		CacheService<Linien> cacheService = new CacheService<Linien>("Linien.class");

		cacheService1.put(2, 2);
		cacheService1.get(2);

		Linien A = new Linien();
		cacheService.put(cacheKey, A);

		System.setProperty("java.util.logging.config.file",
				"e:\\dev\\workspaces\\TiJavaWorkspace\\LessiServer\\GeoLessiImpl\\src\\logging.properties");

		Log log1 = LogFactory.getLog(de.xelerity.geolessi.srv.impl.poi.bahn.HalteSellenGetterFacadeImpl.class);

		// System.out.println(log1);
		// System.out.println(log1.isInfoEnabled());

		de.xelerity.geolessi.srv.impl.poi.bahn.HalteSellenGetterFacadeImpl halteSellenGetterImpl = new HalteSellenGetterFacadeImpl();

		Koordinate pCenterSearch = null;

		pCenterSearch = Koordinate.ZINSHOLZ;

		// pCenterSearch = new Koordinate(48.738334, 9.233827);

		try {
			HalteStellenListe halteStellen = null;// halteSellenGetterImpl.getHalteStellen(pCenterSearch,
																// 600, 0);

			// halteStellen = halteSellenGetterImpl.getHalteStellen(pCenterSearch, 600, 0);

			halteStellen = halteSellenGetterImpl.getHalteStellen(pCenterSearch, 0.010298, 0.010786, 0);

			halteStellen.print();

			for (HalteStelle hs : halteStellen.getHalteStellen()) {
				List<String> iDs = hs.getIDs(HaltestellenIDProvider.BAHN);

				List<NextAbfahrtInfo> res = new HalteStelleNextAbfahrtGetterImpl().getNextAbfahrten(iDs, hs.getHalteStelleTyp(),
						(new java.util.Date().getTime() + Preferences.ServerTimeOffset));

				String HSID = "";
				for (String S : iDs) {
					HSID = HSID + S + ", ";
				}

				System.out.println("------------------------------------------------------------------------- "
						+ HSID.replaceAll(",\\s*$", "") + " ---");
				for (NextAbfahrtInfo nabi : res) {
					System.out.println(nabi.toString());
				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		Test.endTest();
	}
}
